---
description: 'Learn how to implement sales channel functionalities in the storefront using REST APIs. This includes filtering products by Sales Channel and associating a cart with a sales channel.'
addHowToData: true
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# How to Use Sales Channels in Storefronts

In this document, you’ll learn how to use sales channels in your storefront.

## Overview

In your storefront, you can filter products by sales channels. You can also associate carts with a sales channel.

This guide explains how to perform these operations using the Storefront APIs.

### Alternative Approach: Publishable API keys

This guide covers how to pass the sales channel ID into different requests to retrieve or process data associated with the sales channel.

An alternative approach is to use Publishable API keys. You can learn how to use them in the following documents:

- [Using publishable API keys in requests](../../../development/publishable-api-keys/index.mdx)
- Managing publishable API keys using [admin APIs](../../../development/publishable-api-keys/admin/manage-publishable-api-keys.mdx) or using [Medusa Admin](../../../user-guide/settings/publishable-api-keys.mdx)

---

## Prerequisites

### Medusa Components

It's assumed that you already have a Medusa backend installed and set up. If not, you can follow our [quickstart guide](../../../development/backend/install.mdx) to get started.

It is also assumed you already have a storefront set up. It can be a custom storefront or one of Medusa’s storefronts. If you don’t have a storefront set up, you can install the [Next.js starter storefront](../../../starters/nextjs-medusa-starter.mdx).

### JS Client

This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.

If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client installed](../../../js-client/overview.md) and have [created an instance of the client](../../../js-client/overview.md#configuration).

### Medusa React

This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.

If you follow the Medusa React code blocks, it's assumed you already have [Medusa React installed](../../../medusa-react/overview.md) and have [used MedusaProvider higher in your component tree](../../../medusa-react/overview.md#usage).

For requests that use the cart, it's also assumed you already have [used CartProvider higher in your component tree](../../../medusa-react/overview.md#cartprovider).

---

## Filter Products by Sales Channel

To filter products by a specific sales channel, pass the `sales_channel_id` query parameter to the List Products endpoint:

<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>

```ts
medusa.products.list({
  sales_channel_id: [
    salesChannelId,
  ],
})
.then(({ products, limit, offset, count }) => {
  console.log(products.length)
})
```

</TabItem>
<TabItem value="medusa-react" label="Medusa React">

```tsx
import { Product } from "@medusajs/medusa"
import { useProducts } from "medusa-react"

const Products = () => {
  const { products, isLoading } = useProducts({
    sales_channel_id: [
      salesChannelId,
    ],
  })

  return (
    <div>
      {isLoading && <span>Loading...</span>}
      {products && products.length > 0 && (
        <ul>
          {products.map((product: Product) => (
            <li key={product.id}>{product.title}</li>
          ))}
        </ul>
      )}
      {products && !products.length && <span>No Products</span>}
    </div>
  )
}

export default Products
```

</TabItem>
<TabItem value="fetch" label="Fetch API">

<!-- eslint-disable max-len -->

```ts
fetch(`<BACKEND_URL>/store/products?sales_channel_id[0]=${salesChannelId}`)
.then((response) => response.json())
.then(({ products, limit, offset, count }) => {
  console.log(products.length)
})
```

</TabItem>
</Tabs>

The `sales_channel_id` query parameter is an array of sales channel IDs. You can pass more than one sales channel.

The request returns an array of products. These are the products that are available in the sales channel.

---

## Associate a Cart with a Sales Channel

### When Creating a Cart

To associate a sales channel with a cart while creating it, you can pass the `sales_channel_id` request body parameter with the ID of the sales channel:

<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>


```ts
medusa.carts.create({
  sales_channel_id: salesChannelId,
})
.then(({ cart }) => {
  console.log(cart.id)
})
```

</TabItem>
<TabItem value="medusa-react" label="Medusa React">

```tsx
import { useCart } from "medusa-react"

const Cart = () => {
  const { cart, createCart } = useCart()

  const handleCreateCart = () => {
    createCart.mutate(
      {
        sales_channel_id: salesChannelId,
      },
      {
        onSuccess: ({ cart }) => {
          localStorage.setItem("cart_id", cart.id)
        },
      }
    )
  }
  
  // ...
}

export default Cart
```

</TabItem>
<TabItem value="fetch" label="Fetch API">

```ts
fetch(`<BACKEND_URL>/store/carts`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sales_channel_id: salesChannelId,
  }),
})
.then((response) => response.json())
.then(({ cart }) => {
  console.log(cart.id)
})
```

</TabItem>
</Tabs>

The request returns the created cart.

### Updating an Existing Cart

You can update the sales channel of an existing cart by passing the `sales_channel_id` request body parameter with the ID of the sales channel:

<Tabs groupId="request-type" wrapperClassName="code-tabs">
<TabItem value="client" label="Medusa JS Client" default>

```ts
medusa.carts.update(cartId, {
  sales_channel_id: salesChannelId,
})
.then(({ cart }) => {
  console.log(cart.id)
})
```

</TabItem>
<TabItem value="medusa-react" label="Medusa React">

```tsx
import { useCart } from "medusa-react"

const Cart = () => {
  // ...

  const { updateCart } = useCart()

  const changeSalesChannel = (salesChannelId: string) => {
    updateCart.mutate({
      sales_channel_id: salesChannelId,
    })
  }

  // ...
}

export default Cart
```

</TabItem>
<TabItem value="fetch" label="Fetch API">

```ts
fetch(`<BACKEND_URL>/store/carts/${cartId}`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sales_channel_id: salesChannelId,
  }),
})
.then((response) => response.json())
.then(({ cart }) => console.log(cart.id))
```

</TabItem>
</Tabs>

The request returns the updated cart.